package com.cqxyd.smartsite.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.*;

import com.cqxyd.smartsite.pojo.*;
import com.cqxyd.smartsite.service.ProgramInfoService;
import com.sun.javafx.binding.StringFormatter;
import org.apache.commons.codec.digest.DigestUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class PostHelper {
    //private  Logger logger = Logger.getLogger(PostHelper.class);
    private final Logger logger = LoggerFactory.getLogger(PostHelper.class);

    @Value("${supplier_key_id}")
    private String supplierKeyId;

    @Value("${supplier_key_secret}")
    private String supplierKeySecret;

    @Value("${lifter_record_url}")
    private String lifterRecordUrl;

    @Value("${lifter_heartbeat_url}")
    private String lifterHeartbeatUrl;

    @Value("${crane_record_url}")
    private String craneRecordUrl;

    @Value("${crane_heartbeat_url}")
    private String craneHeartbeatUrl;


    @Value("${base_url}")
    private String baseUrl;

    @Value("${env_record_url}")
    private String envRecordUrl;

    @Value("${attendance_url}")
    private String attendanceUrl;

    @Value("${video_info_url}")
    private String videoInfoUrl;

    @Autowired
    private GetHelper getHelper;
    @Autowired
    private ProgramInfoService programInfoService;
    /**
     * 发送普通请求
     *
     * @param URL              地址
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param obj
     * @return
     */
    private JSONResult<String> postRequest(String URL, String programKeyId, String programKeySecret, String obj) {
        String jsonString = "";
        try {

            // 1. 取发送请求时取服务器的UNIX时间戳（服务器时间需要提前与标准时间进行校对），例如：1526438202
            String unixTimeStr = Long.toString(System.currentTimeMillis() / 1000L);
            // 2.
            // 生成一个随机字符串，长度至少10位，由英文字符与数字组成，如：jUY9ybWcM3DH，注意随机字符串每次请求都要不同，不要在不同请求中使用相同随机字符串。
            String randomStr = UUID.randomUUID().toString().replaceAll("\\-", "").toUpperCase();
            // 3. 使用下划线将随机字符串，时间戳与密钥(供应商密钥在前项目密钥在后)拼接为预处理字符串：
            // jUY9ybWcM3DH_1526438202_Ny35o694RgXURrNQ7hCBbI4wyearCWxx7H4n_
            // RMSRvZBhviBiWlddbXil5EqVQhkHJ0WJUbH7
            String preStr = randomStr + "_" + unixTimeStr + "_" + supplierKeySecret + "_"
                    + programKeySecret;
            // 4. 使用sha1
            // Hash算法对预处理字符串进行加密，得到的结果即为签名后的字符串：e914fed7db86318b6d8ce01a6f7cfe463c929f3d
            String signature = DigestUtils.sha1Hex(preStr);
            URL url = new URL(baseUrl + URL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Charsert", "UTF-8");
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/json");
            // 5.将密钥的keyId，随机字符串（rCode），计算签名时的UNIX时间戳以及签名放入http请求的头部,格式为：[供应商keyId]_[项目keyId]，
            // 与数据一起发送给重庆市两江新区智慧工地信息管理平台数据接口。此时HTTP请求头中包含的签名信息如下：
            // keyId=e6fe9dd5-58af-11e8-857d-00163e32d704_1b0f28a4-a5a8-4ea8-ae1a-3b80d6e72397（授权id,以下划线连接，供应商的在前，项目的在后）
            // ts=1526438202（时间戳）
            // rCode= jUY9ybWcM3DH (随机字符串)
            // signature= e914fed7db86318b6d8ce01a6f7cfe463c929f3d（密钥签名）
            connection.setRequestProperty("keyId", supplierKeyId + "_" + programKeyId);
            connection.setRequestProperty("ts", unixTimeStr);
            connection.setRequestProperty("rCode", randomStr);
            connection.setRequestProperty("signature", signature);
            connection.connect();
            PrintWriter out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
            out.println(obj);
            out.flush();
            out.close();
            if (connection.getResponseCode() == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String lines;
                StringBuffer sb = new StringBuffer("");
                while ((lines = reader.readLine()) != null) {
                    lines = new String(lines.getBytes(), "UTF-8");
                    sb.append(lines);
                }
                jsonString = sb.toString();
                reader.close();
                connection.disconnect();
            }else{
                connection.disconnect();
                String info ="使用POST发送信息失败，返回代码："+connection.getResponseCode() ;
                logger.error(info);
                return JSONResult.errorMsg(info);
            }

        } catch (MalformedURLException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return JSONResult.errorMsg(e.getMessage());
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return JSONResult.errorMsg(e.getMessage());
        } catch (IOException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return JSONResult.errorMsg(e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return JSONResult.errorMsg(e.getMessage());
        }
        return JSONResult.ok(jsonString);
    }



    /**
     * 上传升降机信息
     *
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param lifterRecords    升降机信息
     * @return
     */
    public JSONResult<String> postLifterRecord(String programKeyId, String programKeySecret,
                                               List<LifterRecord> lifterRecords) {
        if (lifterRecords.size() <= 50) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                String record = mapper.writeValueAsString(lifterRecords);
                JSONResult<String> result = postRequest(lifterRecordUrl, programKeyId, programKeySecret,
                        record);
                if (!result.isOK()) return result;
                String postResult = result.getData();
                if (!StringUtils.isEmpty(postResult)) {
                    UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                    if (!"0".equals(uploadResult.getCode())) {
                        return getErrorJSONResult(uploadResult);
                    }
                } else {
                    String info = "postRequest返回了空值，发送信息：" + record;
                    logger.error(info);
                    return JSONResult.errorMsg("postRequest返回了空值");
                }
            } catch (IOException e) {
                e.printStackTrace();
                logger.error(e.getMessage());
                return JSONResult.errorMsg(e.getMessage());
            }

        } else {
            // 每次最多不超过50行数据
            for (int i = 0; i < lifterRecords.size() % 50; i++) {

                List<LifterRecord> listToUpload = new ArrayList<LifterRecord>();
                for (int j = i * 50; j < Math.min((i + 1) * 50, lifterRecords.size() - 1); j++) {
                    listToUpload.add(lifterRecords.get(j));
                }
                try {
                    ObjectMapper mapper = new ObjectMapper();
                    String record = mapper.writeValueAsString(listToUpload);
                    JSONResult<String> result = postRequest(lifterRecordUrl, programKeyId, programKeySecret,
                            record);
                    if (!result.isOK()) return result;
                    String postResult = result.getData();
                    if (!StringUtils.isEmpty(postResult)) {
                        UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                        if (!"0".equals(uploadResult.getCode())) {
                            return getErrorJSONResult(uploadResult);
                        }
                    } else {
                        String info = "postRequest返回了空值，发送信息：" + record;
                        logger.error(info);
                        return JSONResult.errorMsg("postRequest返回了空值");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    return JSONResult.errorMsg(e.getMessage());
                }
            }
        }
        return JSONResult.ok("上传升降机信息成功");
    }

    /**
     * 上传升降机心跳信息
     *
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param heartbeat        升降机信息
     * @return
     */
    public JSONResult<String> postLifterHeartbeat(String programKeyId, String programKeySecret,
                                                  Heartbeat heartbeat) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String record = mapper.writeValueAsString(heartbeat);
            JSONResult<String> result = postRequest(lifterHeartbeatUrl, programKeyId, programKeySecret,
                    record);
            if (!result.isOK()) return result;
            String postResult = result.getData();
            if (!StringUtils.isEmpty(postResult)) {
                UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                if (!"0".equals(uploadResult.getCode())) {
                    return getErrorJSONResult(uploadResult);
                }
            } else {
                String info = "postRequest返回了空值，发送信息：" + record;
                logger.error(info);
                return JSONResult.errorMsg("postRequest返回了空值");
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return JSONResult.errorMsg(e.getMessage());
        }
        return JSONResult.ok("上传心跳成功");
    }

    /**
     * 上传塔吊信息
     *
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param craneRecords     塔吊信息
     * @return
     */
    public JSONResult<String> postCraneRecord(String programKeyId, String programKeySecret,
                                              List<CraneRecord> craneRecords) {
        ObjectMapper mapper = new ObjectMapper();
        // 每次最多不超过50行数据
        if (craneRecords.size() <= 50) {
            try {
                String record = mapper.writeValueAsString(craneRecords);
                JSONResult<String> result = postRequest(craneRecordUrl, programKeyId, programKeySecret,
                        record);
                if (!result.isOK()) return result;
                String postResult = result.getData();
                if (!StringUtils.isEmpty(postResult)) {
                    UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                    if (!"0".equals(uploadResult.getCode())) {
                        return getErrorJSONResult(uploadResult);
                    }
                } else {
                    String info = "postRequest返回了空值，发送信息：" + record;
                    logger.error(info);
                    return JSONResult.errorMsg("postRequest返回了空值");
                }
            } catch (IOException e) {
                e.printStackTrace();
                logger.error(e.getMessage());
                return JSONResult.errorMsg(e.getMessage());
            }
        } else {
            for (int i = 0; i < craneRecords.size() % 50; i++) {
                List<CraneRecord> listToUpload = new ArrayList<CraneRecord>();
                for (int j = i * 50; j < Math.min((i + 1) * 50, craneRecords.size() - 1); j++) {
                    listToUpload.add(craneRecords.get(j));
                }
                try {
                    String record = mapper.writeValueAsString(listToUpload);
                    JSONResult<String> result = postRequest(craneRecordUrl, programKeyId, programKeySecret,
                            record);
                    if (!result.isOK()) return result;
                    String postResult = result.getData();
                    if (!StringUtils.isEmpty(postResult)) {
                        UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                        if (!"0".equals(uploadResult.getCode())) {
                            return getErrorJSONResult(uploadResult);
                        }
                    } else {
                        String info = "postRequest返回了空值，发送信息：" + record;
                        logger.error(info);
                        return JSONResult.errorMsg("postRequest返回了空值");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    return JSONResult.errorMsg(e.getMessage());
                }
            }
        }

        return JSONResult.ok("上传塔吊信息成功");
    }

    /**
     * 上传升降机心跳信息
     *
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param heartbeat        升降机信息
     * @return
     */
    public JSONResult<String> postCraneHeartbeat(String programKeyId, String programKeySecret,
                                                 Heartbeat heartbeat) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String record = mapper.writeValueAsString(heartbeat);
            JSONResult<String> result = postRequest(craneHeartbeatUrl, programKeyId, programKeySecret,
                    record);
            if (!result.isOK()) return result;
            String postResult = result.getData();
            if (!StringUtils.isEmpty(postResult)) {
                UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                if (!"0".equals(uploadResult.getCode())) {
                    return getErrorJSONResult(uploadResult);
                }
            } else {
                String info = "postRequest返回了空值，发送信息：" + record;
                logger.error(info);
                return JSONResult.errorMsg("postRequest返回了空值");
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return JSONResult.errorMsg(e.getMessage());
        }
        return JSONResult.ok("上传心跳成功");
    }

    /**
     * 上传环境监测信息
     *
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param envRecords       环境监测信息
     * @return
     */
    public JSONResult<String> postEnvRecord(String programKeyId, String programKeySecret,
                                            List<EnvRecord> envRecords) {
        ObjectMapper mapper = new ObjectMapper();
        // 每次最多不超过50行数据
        if (envRecords.size() <= 50) {
            try {
                String record = mapper.writeValueAsString(envRecords);
                JSONResult<String> result = postRequest(envRecordUrl, programKeyId, programKeySecret,
                        record);
                if (!result.isOK()) return result;
                String postResult = result.getData();
                if (!StringUtils.isEmpty(postResult)) {
                    UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                    if (!"0".equals(uploadResult.getCode())) {
                        return getErrorJSONResult(uploadResult);
                    }
                } else {
                    String info = "postRequest返回了空值，发送信息：" + record;
                    logger.error(info);
                    return JSONResult.errorMsg("postRequest返回了空值");
                }
            } catch (IOException e) {
                e.printStackTrace();
                logger.error(e.getMessage());
                return JSONResult.errorMsg(e.getMessage());
            }
        } else {
            for (int i = 0; i < envRecords.size() % 50; i++) {

                List<EnvRecord> listToUpload = new ArrayList<EnvRecord>();
                for (int j = i * 50; j < Math.min((i + 1) * 50, envRecords.size() - 1); j++) {
                    listToUpload.add(envRecords.get(j));
                }
                try {
                    String record = mapper.writeValueAsString(listToUpload);

                    JSONResult<String> result = postRequest(envRecordUrl, programKeyId, programKeySecret,
                            record);
                    if (!result.isOK()) return result;
                    String postResult = result.getData();
                    if (!StringUtils.isEmpty(postResult)) {
                        UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                        if (!"0".equals(uploadResult.getCode())) {
                            return getErrorJSONResult(uploadResult);
                        }
                    } else {
                        String info = "postRequest返回了空值，发送信息：" + record;
                        logger.error(info);
                        return JSONResult.errorMsg("postRequest返回了空值");
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    return JSONResult.errorMsg(e.getMessage());
                }
            }
        }

        return JSONResult.ok("上传环境监测信息成功");
    }

    /**
     * 上传监控信息
     *
     * @param programKeyId     项目编码
     * @param programKeySecret 项目密匙
     * @param records          人员考勤信息
     * @return
     */
    public JSONResult<String> postVideoRecord(String programKeyId, String programKeySecret,
                                                   List<VideoRecord> records) {
        ObjectMapper mapper = new ObjectMapper();
        // 每次最多不超过50行数据
        if (records.size() <= 50) {
            try {
                String record = mapper.writeValueAsString(records);
                JSONResult<String> result = postRequest(videoInfoUrl, programKeyId, programKeySecret,
                        record);
                if (!result.isOK()) return result;
                String postResult = result.getData();
                if (!StringUtils.isEmpty(postResult)) {
                    UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                    if (!"0".equals(uploadResult.getCode())) {
                        return getErrorJSONResult(uploadResult);
                    }
                } else {
                    String info = "postRequest返回了空值，发送信息：" + record;
                    logger.error(info);
                    return JSONResult.errorMsg("postRequest返回了空值");
                }
            } catch (IOException e) {
                e.printStackTrace();
                logger.error(e.getMessage());
                return JSONResult.errorMsg(e.getMessage());
            }
        } else {
            for (int i = 0; i < records.size() % 50; i++) {

                List<VideoRecord> listToUpload = new ArrayList<VideoRecord>();
                for (int j = i * 50; j < Math.min((i + 1) * 50, records.size() - 1); j++) {
                    listToUpload.add(records.get(j));
                }
                try {
                    String record = mapper.writeValueAsString(listToUpload);
                    JSONResult<String> result = postRequest(attendanceUrl, programKeyId, programKeySecret,
                            record);
                    if (!result.isOK()) return result;
                    String postResult = result.getData();

                    if (!StringUtils.isEmpty(postResult)) {
                        UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                        if (!"0".equals(uploadResult.getCode())) {
                            return getErrorJSONResult(uploadResult);
                        }
                    } else {
                        String info = "postRequest返回了空值，发送信息：" + record;
                        logger.error(info);
                        return JSONResult.errorMsg("postRequest返回了空值");
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    return JSONResult.errorMsg(e.getMessage());
                }
            }
        }

        return JSONResult.ok("上传监控信息成功");
    }


    /**
     * 上传人员考勤信息
     *
     * @return
     */
    public JSONResult<String> postAttendanceRecord() {
        ObjectMapper mapper = new ObjectMapper();
        String programKeyId ="";
        String programKeySecret ="";

        Integer pageNo = 1;
        Integer uploadCount = 0;
        Date endTime = new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(endTime);
        cal.add(Calendar.DATE, -10);
        Date startTime = cal.getTime();

        //下载考勤记录
        JSONResult<List<AttendanceDownloadDetial>> detialListResult = getHelper.getAttendanceRecord(pageNo,10,startTime,endTime);
        List<AttendanceDownloadDetial> detialList=detialListResult.getData();
       /* while (detialListResult.isOK() && detialList!=null && detialList.size()>0)
        {*/
            uploadCount +=detialList.size();
            List<AttendanceRecord> records = new ArrayList<AttendanceRecord>();
            for (AttendanceDownloadDetial detial:detialList) {
                String devSn = detial.getDevSn();
                if (StringUtils.isEmpty(programKeyId)){
                    List<String> keyAndSecret = programInfoService.getKeyAndSecret(devSn);
                    if (keyAndSecret != null){
                        programKeyId = keyAndSecret.get(0);
                        programKeySecret = keyAndSecret.get(1);
                    }else{
                        String info = MessageFormat.format("考勤设备（{0}）未注册",devSn);
                        logger.error(info);
                        return JSONResult.errorMsg(info);
                    }
                }
                AttendanceRecord newRecord = new AttendanceRecord();
                newRecord.setWorkerId("6FC1971B-E682-4B05-A385-91C38C1FBFC1");
                newRecord.setEntry("Entry");//Entry：进场 Exit：出场
                newRecord.setMode("Face"); //verifyModeName
                newRecord.setAttendanceTime(detial.getEventTime());
                newRecord.setSn("123");
                newRecord.setPhoto("");
                newRecord.setLng(0);
                newRecord.setLat(0);
                records.add(newRecord);
            }

            // 每次最多不超过50行数据
            if (records.size() <= 50) {
                try {
                    String record = mapper.writeValueAsString(records);
                    JSONResult<String> result = postRequest(attendanceUrl, programKeyId, programKeySecret,
                            record);
                    if (!result.isOK()) return result;
                    String postResult = result.getData();
                    if (!StringUtils.isEmpty(postResult)) {
                        UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                        if (!"0".equals(uploadResult.getCode())) {
                            return getErrorJSONResult(uploadResult);
                        }
                    } else {
                        String info = "postRequest返回了空值，发送信息：" + record;
                        logger.error(info);
                        return JSONResult.errorMsg("postRequest返回了空值");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    return JSONResult.errorMsg(e.getMessage());
                }
            } else {
                for (int i = 0; i < records.size() % 50; i++) {

                    List<AttendanceRecord> listToUpload = new ArrayList<AttendanceRecord>();
                    for (int j = i * 50; j < Math.min((i + 1) * 50, records.size() - 1); j++) {
                        listToUpload.add(records.get(j));
                    }
                    try {
                        String record = mapper.writeValueAsString(listToUpload);
                        JSONResult<String> result = postRequest(videoInfoUrl, programKeyId, programKeySecret,
                                record);
                        if (!result.isOK()) return result;
                        String postResult = result.getData();

                        if (!StringUtils.isEmpty(postResult)) {
                            UploadResult uploadResult = mapper.readValue(postResult, UploadResult.class);
                            if (!"0".equals(uploadResult.getCode())) {
                                return getErrorJSONResult(uploadResult);
                            }
                        } else {
                            String info = "postRequest返回了空值，发送信息：" + record;
                            logger.error(info);
                            return JSONResult.errorMsg("postRequest返回了空值");
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                        logger.error(e.getMessage());
                        return JSONResult.errorMsg(e.getMessage());
                    }
                }
            }
        /*    pageNo++;
            detialListResult = getHelper.getAttendanceRecord(pageNo,50,startTime,endTime);
        }*/

        if (detialListResult.isOK()){
            return JSONResult.ok("上传人员考勤信息成功，本次上传"+uploadCount+"条。");
        }else{
            return JSONResult.errorMsg(detialListResult.getMsg());
        }
    }




    private JSONResult<String> getErrorJSONResult(UploadResult uploadResult) {
        logger.error(uploadResult.toString());
        switch (uploadResult.getCode()) {
            case "1":
                return JSONResult.errorMsg("参数格式:" + uploadResult.toString());
            case "2":
                return JSONResult.errorMsg("数据错误:" + uploadResult.toString());
            case "3":
                return JSONResult.errorMsg("无操作权限:" + uploadResult.toString());
            case "4":
                return JSONResult.errorMsg("系统异常:" + uploadResult.toString());
        }
        return JSONResult.errorMsg("未知错误:" + uploadResult.toString());
    }


}
